我们在使用 Node.js 开发时,经常会用到很多命令行工具,
有些工具我们会通过 npm i -g
安装,安装完后我们就有了一个新的命令,可以在任何地方使用。
例如前面的 tsx
,pm2
,yrm
等,在随 npm 包安装的时候就完成了一些命令的注册。
本章节我们就来学习如何开发一个命令行工具,大体上和 npm 包开发一样,只有 package.json
里配置有一些不同。
PS:本章不会介绍原理,关于原理可以阅读文章:Node CLI 工具原理解析。
和 npm 包开发流程一样,这里不做重复介绍 (大家可以先看 npm 开发实践),只讲过程中不一样的地方。
目录结构如下。
sh
├── package.json
└── src
├── bin.ts
└── index.ts
多一个 src/bin.ts
文件,将这个文件是命令行工具的入口文件。
代码如下。
```ts
const argvs = process.argv.slice(2) console.log('argvs', argvs)
console.log('Hello, world!') ```
其中首行是 Hashbang
,这个我们在之前的本地运行有介绍过。
Hashbang (也称为 shebang) 是一种特殊的注释,以
#!
开头,通常出现在可执行的脚本文件的第一行,用于告诉系统要使用哪个解释器来执行该脚本文件。
同样的我们这里使用 tsup
构建,支持设置多个入口文件。
json
{
"scripts": {
"build": "tsup src/index.ts src/bin.ts --target es6 --format cjs,esm --dts",
"dev": "tsup src/index.ts src/bin.ts --target es6 --format cjs,esm --dts --watch"
}
}
构建后会有 dist/bin.js
文件,这个就是我们最后实际运行的文件。
在 package.json
中,我们可以配置 bin
属性,这个属性是用来指定命令行工具的入口文件的。
比如我们设置一个 hello-node
命令,将指向 dist/bin.js
文件。
json
{
"bin": {
"hello-node": "dist/bin.js"
}
}
到这开发和配置基本就完成了。
当我们本地安装这个包的时候,就会在 node_modules/.bin
目录下生成一个 hello-node
的可执行文件,这个文件就是我们的命令行工具。
我们在这个项目里可以使用 npx hello-node
来运行这个命令。
如果想在任意地方调用。
我们可以通过 npm link
将这个包链接到全局,然后就可以在任何地方使用 hello-node
命令了。
PS:如果这个包被发布到了 npm 上,咱们就可以直接 npm i -g xxx
直接安装启用。
框架一般主要负责的就是命令行参数的解析和校验。
社区有很多优秀的命令行框架,比如较出名的 Commander、cac 等。
这里我们使用 Commander 来实践一下。
① 先安装依赖
sh
npm i commander
② 创建一个文件 src/commander-test.ts
加入如下内容
```ts
// 引入Command类和package.json文件
import { Command } from 'commander'
import pkg from '../package.json'
// 创建程序实例并设置版本号
const program = new Command()
program.version(pkg.version)
// 添加命令hello和描述,别名为h,支持选项--exclude和--allow-dirty
program
.command('hello [name]')
.description('打招呼')
.alias('h')
.option('-e, --exclude
然后将这个文件添加到构建指令里,构建出 dist
目录下的资源。
③ 设定指令 node-hello
在 package.json
中追加如下内容,一个 npm 包可以注册多个指令。
json
{
"bin": {
"hello-node": "dist/bin.js",
"node-hello": "dist/commander-test.js"
}
}
④ 按照上述的方式测试一下效果
可以看到框架自动为我们注册了指令和 --help
等额外选项等等。
执行效果如下。
到这里,我们就完成了一个简单的命令行工具的开发,其发布流程和 npm 包流程完全一致。
本节详细的介绍了,如何使用 Node.js 开发一个命令行工具,以及如何使用框架来简化开发流程,
其中最为关键的部分就是,package.json 中的 bin 属性,用来指定命令行工具的入口文件。
使用框架,可以简化命令行参数的解析和校验,提高开发效率,并自动生成友好的提示信息。
命令行工具最终发布也是一个 npm 包,其发布流程和普通 npm 包流程完全一致。
如果觉得内容不够看,推荐大家阅读: